package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.field.MultiUnitItemPoJo;
import com.xbongbong.paas.field.UnitItemPoJo;
import com.xbongbong.paas.help.FormDataValidateProductHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.pro.constant.BusinessConstant;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.OutstockErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ProductErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.ImportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SettleAccountErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.WarehouseErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.oriStock.pojo.OriStockSaveDTO;
import com.xbongbong.pro.service.toolbox.elasticsearch.help.ProEsHelper;
import com.xbongbong.pro.workorder.pojo.dto.WarehouseOriDeleteBatchDTO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.ProductConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.BatchFlowBillUpdateEntity;
import com.xbongbong.saas.domain.entity.InstockProductEntity;
import com.xbongbong.saas.domain.entity.OutstockProductEntity;
import com.xbongbong.saas.domain.entity.ProductSerialBalanceEntity;
import com.xbongbong.saas.domain.entity.ProductSerialFlowEntity;
import com.xbongbong.saas.domain.entity.ProductStockUpdateEntity;
import com.xbongbong.saas.domain.entity.ProductWarehouseEntity;
import com.xbongbong.saas.domain.entity.SettleAccountsEntity;
import com.xbongbong.saas.domain.entity.StockFlowBillUpdateEntity;
import com.xbongbong.saas.domain.entity.WarehouseOristockEntity;
import com.xbongbong.saas.domain.entity.WarehouseOristockProductEntity;
import com.xbongbong.saas.domain.entity.ext.ProductEntityExt;
import com.xbongbong.saas.domain.entity.ext.WarehouseEntityExt;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SelectProductEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.InstockEnum;
import com.xbongbong.saas.enums.business.OriStockEnum;
import com.xbongbong.saas.enums.business.ProductEnum;
import com.xbongbong.saas.enums.business.SerialEnum;
import com.xbongbong.saas.enums.business.WarehouseEnum;
import com.xbongbong.saas.enums.dictionary.WarehouseOriStockEnum;
import com.xbongbong.saas.enums.product.OriStockProductEnum;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.RelativeProductHelp;
import com.xbongbong.saas.help.SaasDeleteHelp;
import com.xbongbong.saas.help.SaasSaveHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.model.InstockProductModel;
import com.xbongbong.saas.model.OutstockProductModel;
import com.xbongbong.saas.model.ProductModel;
import com.xbongbong.saas.model.ProductSerialBalanceModel;
import com.xbongbong.saas.model.ProductSerialFlowModel;
import com.xbongbong.saas.model.ProductWarehouseModel;
import com.xbongbong.saas.model.SettleAccountsModel;
import com.xbongbong.saas.model.WarehouseModel;
import com.xbongbong.saas.model.WarehouseOristockModel;
import com.xbongbong.saas.model.WarehouseOristockProductModel;
import com.xbongbong.saas.service.BatchFlowBillService;
import com.xbongbong.saas.service.InstockProductService;
import com.xbongbong.saas.service.InstockService;
import com.xbongbong.saas.service.OriStockService;
import com.xbongbong.saas.service.ProductSerialService;
import com.xbongbong.saas.service.ProductService;
import com.xbongbong.saas.service.StockFlowBillService;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.model.CompanyConfigModel;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Program xbb-pro
 * @Description
 * @Author caoyy
 * @Date 2019/10/16
 **/
@Service("oriStockService")
public class OriStockServiceImpl implements OriStockService {
    private static final Logger LOG = LoggerFactory.getLogger(OriStockServiceImpl.class);
    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private WarehouseOristockModel warehouseOristockModel;
    @Resource
    private WarehouseOristockProductModel warehouseOristockProductModel;
    @Resource
    private WarehouseModel warehouseModel;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private ProductWarehouseModel productWarehouseModel;
    @Resource
    private ProductModel productModel;
    @Resource
    private ProductService productService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private SaasSaveHelp saasSaveHelp;
    @Resource
    private InstockProductService instockProductService;
    @Resource
    private StockFlowBillService stockFlowBillService;
    @Resource
    private ProEsHelper proEsHelper;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private InstockService instockService;
    @Resource
    private InstockProductModel instockProductModel;
    @Resource
    private OutstockProductModel outstockProductModel;
    @Resource
    private CompanyConfigModel companyConfigModel;
    @Resource
    private BatchFlowBillService batchFlowBillService;
    @Resource
    private ProductSerialBalanceModel productSerialBalanceModel;
    @Resource
    private ProductSerialFlowModel productSerialFlowModel;
    @Resource
    private ProductSerialService productSerialService;
    @Resource
    private SaasDeleteHelp saasDeleteHelp;
    @Resource
    private FormDataValidateProductHelp formDataValidateProductHelp;
    @Resource
    private RelativeProductHelp relativeProductHelp;
    @Resource
    private SettleAccountsModel settleAccountsModel;

    /**
    * @Description:  关联数据格式化解释
    * @Param: [handlerExplainInLinkItemDTO]
    * @return: void
    * @Author: cyy
    * @Date: 2019/10/16
    */
    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        JSONObject linkFormData = handlerExplainInLinkItemDTO.getLinkFormData();
        Long linkDataId = handlerExplainInLinkItemDTO.getLinkDataId();
        Integer linkBusinessType = handlerExplainInLinkItemDTO.getLinkBusinessType();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        PaasFormDataEntityExt paasFormDataEntityExt = handlerExplainInLinkItemDTO.getPaasFormDataEntityExt();
        String corpid = paasFormDataEntityExt.getCorpid();

        FieldAttrEntity linkWarehouseField = new FieldAttrEntity();
        for(FieldAttrEntity fieldAttrEntity :explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), OriStockEnum.WAREHOUSE.getAttr())) {
                linkWarehouseField = fieldAttrEntity;
            }
            if (Objects.equals(fieldAttrEntity.getAttr(),OriStockEnum.PRODUCT_DETAIL.getAttr())){
                PaasFormEntity paasFormEntity = paasFormModel.getByBusinessType(XbbRefTypeEnum.PRODUCT.getCode(),corpid);
                List<? extends FieldAttrEntity> subExplainList = fieldAttrEntity.getSubForm().getItems();
                Iterator<? extends FieldAttrEntity> iterator = subExplainList.iterator();
                while (iterator.hasNext()){
                    FieldAttrEntity subFieldAttrEntity = iterator.next();
                    if (!Objects.equals(subFieldAttrEntity.getAttr(),SelectProductEnum.PRODUCT.getAttr())){
                        continue;
                    }
                    subFieldAttrEntity.getLinkInfo().setLinkAppId(paasFormEntity.getAppId());
                    subFieldAttrEntity.getLinkInfo().setLinkMenuId(paasFormEntity.getMenuId());
                    subFieldAttrEntity.getLinkInfo().setLinkFormId(paasFormEntity.getId());
                    break;
                }

            }
        }
        explainList.removeIf(fieldAttrEntity -> (Objects.equals(fieldAttrEntity.getAttr(),OriStockEnum.ADD_TIME.getAttr())
                || Objects.equals(fieldAttrEntity.getAttr(),OriStockEnum.UPDATE_TIME.getAttr()) || Objects.equals(fieldAttrEntity.getAttr(),OriStockEnum.CREATOR_ID.getAttr())));
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(handlerExplainInLinkItemDTO.getLinkBusinessType());
        switch (redundantTemplateTypeEnum) {
            case WAREHOUSE:
                String warehouseName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, WarehouseEnum.WAREHOUSE_NAME.getAttr(), "");
                linkWarehouseField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, warehouseName));
                linkWarehouseField.setEditable(0);
                break;
            default:
                break;
        }

    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException{
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        String corpid = importFormDataDTO.getCorpid();
        formDataAddDTO.setSerialNo("");
        JSONObject dataJson = new JSONObject();
        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);

        for (FieldAttrEntityForImport fieldAttr : fieldAttrList) {
            String attr = fieldAttr.getAttr();
            Integer fieldType = fieldAttr.getFieldType();
            String attrName = fieldAttr.getAttrName();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);

            if (Objects.equals(attr, OriStockEnum.PRODUCT_DETAIL.getAttr())) {
                importHelper.formatCommonProduct(titlePojoList, dataJson, rowValueList, fieldAttr, XbbRefTypeEnum.ORI_STOCK.getCode(), corpid);
            } else if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, fieldAttr, dataJson);
            } else {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                if (Objects.equals(attr, OriStockEnum.WAREHOUSE.getAttr())) {
                    List<ItemPoJo> itemPoJoList = fieldAttr.getItems();
                    JSONArray jsonArray = new JSONArray();
                    for (ItemPoJo itemPoJo : itemPoJoList) {
                        if (Objects.equals(cellValue.toString(), itemPoJo.getText())) {
                            JSONObject jsonObject = new JSONObject();
                            jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_ID, itemPoJo.getValue());
                            jsonObject.put(StringConstant.SAAS_LINK_BUSINESS_NAME, itemPoJo.getText());
                            jsonObject.put(StringConstant.VALUE, itemPoJo.getText());
                            jsonArray.add(jsonObject);
                            break;
                        }
                    }
                    if (jsonArray.isEmpty()) {
                        throw new XbbException(ImportErrorCodeEnum.API_ERROR_235037);
                    }
                    dataJson.put(attr, jsonArray);
                } else if (ImportHelper.commonHandleFieldType.contains(fieldAttr.getFieldType())) {
                    importHelper.formatCommonField(dataJson, fieldAttr, cellValue);
                } else {
                    if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                        formDataAddDTO.setSerialNo(cellValue.toString());
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                        importHelper.formatLinkData(cellValue, fieldAttr, dataJson);
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                        importHelper.formatLinkDataMulti(cellValue, importFormDataDTO, fieldAttr, dataJson);
                    } else {
                        dataJson.put(attr, cellValue);
                    }
                }
            }
        }
        formDataAddDTO.setDataList(dataJson);
        return formDataAddDTO;
    }

    /**
    * @Description: 期初库存保存
    * @Param: [oriStockSaveDTO]
    * @return: void
    * @Author: cyy
    * @Date: 2019/10/16
    */
    @Transactional(rollbackFor = Exception.class)
    @Override
//    @ConcurrentLock(businessType = HandleProductWayEnum.ADD)
    public FormDataAddVO add(OriStockSaveDTO oriStockSaveDTO) throws XbbException{
        FormDataAddVO formDataAddVO = new FormDataAddVO();
        ValidateDataDTO validateDataDTO = new ValidateDataDTO();
        BeanUtil.copyProperties(oriStockSaveDTO, validateDataDTO);
        validateDataDTO.setData(oriStockSaveDTO.getDataList());
        String corpid = oriStockSaveDTO.getCorpid();
        boolean isImport = Objects.equals(1, oriStockSaveDTO.getIsImport());
        // 期初新建的权限校验====================================
        UserVO loginUser = oriStockSaveDTO.getLoginUser();
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.WAREHOUSE_ADD.getAlias())
                || !loginUser.getPermSet().contains(ProPermissionAliasEnum.WAREHOUSE_UPDATE.getAlias())){
            throw new XbbException(WarehouseErrorCodeEnum.API_ERROR_244021);
        }
        //结账中校验
        //期初没有单据时间-也因为期初库存会影响整个产品库存，就是不让创建-就是创建时间--当前时间
        String redisHelperValue = paasRedisHelper.getValue(RedisPrefixConstant.SETTLE_ACCOUNTS, corpid);
        if (StringUtil.isNotEmpty(redisHelperValue)) {
            if (DateTimeUtil.getTodayInt() <= DateTimeUtil.getTodayEndInt(Long.valueOf(redisHelperValue))){
                throw new XbbException(SettleAccountErrorCodeEnum.API_ERROR_254007);
            }
        }
        SettleAccountsEntity accountsEntity = settleAccountsModel.getLastSettleAccounts(corpid);
        //校验日期是否受结账限制
        if (Objects.nonNull(accountsEntity) && Objects.nonNull(accountsEntity.getCheckOutTime())) {
            if (DateTimeUtil.getTodayInt() <= DateTimeUtil.getTodayEndInt(accountsEntity.getCheckOutTime())) {
                throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212051);
            }
        }
        String value = paasRedisHelper.getValue(RedisPrefixConstant.PRODUCE_STOCK_FLOW, corpid);
        if (StringUtil.isNotEmpty(value)) {
            throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212038);
        }
        JSONObject dataList = oriStockSaveDTO.getDataList();
        saasSaveHelp.formatLinkBusiness4Save(dataList, OriStockEnum.WAREHOUSE.getAttr(), OriStockEnum.WAREHOUSE_LINK_TEXT.getAttr(), OriStockEnum.WAREHOUSE.getFieldType());
        Long warehouseId = dataList.getLong(OriStockEnum.WAREHOUSE.getAttr());
        if (Objects.isNull(warehouseId)){
            throw new XbbException(WarehouseErrorCodeEnum.API_ERROR_244005);
        }
        // 仓库状态校验
        WarehouseEntityExt warehouseEntityExt = warehouseModel.getByKey(warehouseId,corpid);
        if (Objects.isNull(warehouseEntityExt)){
            throw new XbbException(WarehouseErrorCodeEnum.API_ERROR_244005);
        }
        JSONObject warehouseJsonData = warehouseEntityExt.getData();
        if (Objects.isNull(warehouseJsonData.getInteger(WarehouseEnum.ORI_STOCK.getAttr()))||
                Objects.equals(warehouseJsonData.getString(WarehouseEnum.ORI_STOCK.getAttr()),WarehouseOriStockEnum.NO_NEED.getCode())){
            throw new XbbException(WarehouseErrorCodeEnum.API_ERROR_244022);
        }
        String warehouseName = warehouseJsonData.getString(WarehouseEnum.WAREHOUSE_NAME.getAttr());
        // 此仓库是否已经有期初
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put(ParameterConstant.CORPID,corpid);
        params.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        params.put(ParameterConstant.WAREHOUSE_ID, warehouseId);
        List<WarehouseOristockEntity> warehouseOristockEntityList = warehouseOristockModel.findEntitys(params);
        if (CollectionsUtil.isNotEmpty(warehouseOristockEntityList)){
            throw new XbbException(WarehouseErrorCodeEnum.API_ERROR_244019);
        }
        // 是否有分仓库存
        params.put("numNot",0);
        params.put("warehouseChecked", 1);
        List<ProductWarehouseEntity> productWarehouseEntityList = productWarehouseModel.findEntitysWithWarehouseChecked(params,1);
        if (CollectionsUtil.isNotEmpty(productWarehouseEntityList)){
            throw new XbbException(WarehouseErrorCodeEnum.API_ERROR_244020);
        }

        JSONArray productArr = dataList.getJSONArray(OriStockEnum.PRODUCT_DETAIL.getAttr());
        if (Objects.isNull(productArr) || productArr.size() == 0) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100040);
        }
        List<Long> productIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (int i = 0; i < productArr.size(); i++) {
            JSONObject jsonObject = productArr.getJSONObject(i);
            JSONObject productDetail = jsonObject.getJSONObject(SelectProductEnum.PRODUCT.getAttr());
            Long dataId = productDetail.getLong(FieldTypeEnum.DATAID.getAlias());
            jsonObject.put(SelectProductEnum.PRODUCT.getAttr(), dataId);
            jsonObject.put(SelectProductEnum.WAREHOUSE.getAttr(), warehouseId);
            productIdList.add(dataId);
        }
        dataList.put(OriStockEnum.PRODUCT_DETAIL.getAttr(), productArr);
        Map<Long, ProductEntityExt> productMap = productModel.getProductMapByIdIn(corpid, productIdList, DelEnum.NORMAL.getDel());
        //期初用实时开关数据
        JSONObject data = validateDataDTO.getData();
        JSONArray productJsonArray = data.getJSONArray(InstockEnum.PRODUCT.getAttr());
        for (int i = 0; i < productJsonArray.size(); i++) {
            JSONObject productData = productJsonArray.getJSONObject(i);
            Long productKey = productData.getLong(OriStockProductEnum.PRODUCT.getAttr());
            productData.put(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getSaasAttr(),productMap.get(productKey).getData().get(ProductEnum.ENABLE_BATCH_SHELF_LIFE.getAttr()));
            productData.put(ProductEnum.ENABLE_SERIAL_NUMBER.getSaasAttr(),productMap.get(productKey).getData().get(ProductEnum.ENABLE_SERIAL_NUMBER.getAttr()));
        }
        saasSaveHelp.batchSaveRequiredCheck(validateDataDTO);
        List<WarehouseOristockProductEntity> addWarehouseOristockProductEntityList = new ArrayList<>(productArr.size());
        List<InstockProductEntity> instockProductList = new ArrayList<>(productArr.size());
        Map<Long, UnitItemPoJo> unitItemPoJoMap;
        Long unit;
        for (int i = 0; i < productArr.size(); i++) {
            JSONObject jsonObject = productArr.getJSONObject(i);
            Long dataId = jsonObject.getLong(SelectProductEnum.PRODUCT.getAttr());
            if (!productMap.containsKey(dataId)) {
                LOG.error("该规格的产品找不到了，产品在saas_product的id为：" + dataId + "公司id:" +  corpid);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            Double num = jsonObject.getDouble(SelectProductEnum.NUM.getAttr());
            String batch = Objects.isNull(jsonObject.getString(SelectProductEnum.BATCH.getAttr())) ? "" : jsonObject.getString(SelectProductEnum.BATCH.getAttr());
            Long produceDate = Objects.isNull(jsonObject.getLong(SelectProductEnum.PRODUCE_DATE.getAttr())) ? 0L : jsonObject.getLong(SelectProductEnum.PRODUCE_DATE.getAttr());
            Long guaranteePeriod = Objects.isNull(jsonObject.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr())) ? 0L : jsonObject.getLong(SelectProductEnum.GUARANTEE_PERIOD.getAttr());

            ProductEntityExt productEntityExt = productMap.get(dataId);
            JSONObject productObj = productEntityExt.getData();
            Double cost = productObj.getDouble(ProductEnum.COST.getAttr());
            jsonObject.put(SelectProductEnum.COST.getAttr(), cost);
            Long parentId = productObj.getLong(ProductEnum.PARENT_ID.getAttr());
            WarehouseOristockProductEntity warehouseOristockProductEntity = new WarehouseOristockProductEntity();
            Integer enableMultiUnit = productObj.getInteger(ProductEnum.ENABLE_MULTI_UNIT.getAttr());
            if (Objects.equals(enableMultiUnit, 1)) {
                unitItemPoJoMap= FastJsonHelper.getJsonArrOrDefaultFromFormData(jsonObject, ProductConstant.TRANSFORM_UNIT_RATE, new JSONArray()).toJavaList(UnitItemPoJo.class)
                        .stream().collect(Collectors.toMap(UnitItemPoJo::getValue, unitItemPoJo -> unitItemPoJo));
                unit = jsonObject.getJSONObject(ProductEnum.UNIT.getAttr()).getLong(BasicConstant.VALUE);
                UnitItemPoJo businessUnitItem = unitItemPoJoMap.get(unit);
                //期初基本单位的产品单位回显异常
                if (Objects.nonNull(businessUnitItem)) {
                    MultiUnitItemPoJo unitGroup = relativeProductHelp.getGroupMessage(corpid, businessUnitItem.getGroupId());
                    Double rate = businessUnitItem.getRate();
                    jsonObject.put(SelectProductEnum.NUM.getAttr(), Arith.mul(num, rate));
                    jsonObject.put(SelectProductEnum.BUSINESS_NUM.getAttr(), num);
                    jsonObject.put(SelectProductEnum.BUSINESS_UNIT.getAttr(), unit);
                    jsonObject.put(SelectProductEnum.RATE.getAttr(), rate);
                    jsonObject.put(SelectProductEnum.UNIT_GROUP.getAttr(), businessUnitItem.getGroupId());
                    jsonObject.put(SelectProductEnum.UNIT.getAttr(), unitGroup.getBaseValue());
                }
                warehouseOristockProductEntity.setUnit(businessUnitItem.getGroupId().toString());
                formDataValidateProductHelp.setBusinessUnit(jsonObject, warehouseOristockProductEntity);
            }
            warehouseOristockProductEntity.setCorpid(corpid);
            warehouseOristockProductEntity.setParentId(parentId);
            warehouseOristockProductEntity.setProductNo(productEntityExt.getSerialNo());
            warehouseOristockProductEntity.setProductBarcode(productObj.getString(ProductEnum.BARCODE.getAttr()));
            String specStr = productService.decodeSpec(productEntityExt.getData().getString(ProductEnum.SPECIFICATION.getAttr()), productEntityExt.getData().getString(ProductEnum.SPECIFICATION_LINK_TEXT.getAttr()), null);
            warehouseOristockProductEntity.setSpec(specStr);
            warehouseOristockProductEntity.setCost(cost);
            warehouseOristockProductEntity.setProductName(productObj.getString(ProductEnum.NAME.getAttr()));
            warehouseOristockProductEntity.setOristockNum(jsonObject.getDouble(SelectProductEnum.NUM.getAttr()));
            warehouseOristockProductEntity.setMemo(jsonObject.getString(SelectProductEnum.MEMO.getAttr()));
            warehouseOristockProductEntity.setProductId(dataId);
            warehouseOristockProductEntity.setData(jsonObject);
            warehouseOristockProductEntity.setBatch(batch);
            warehouseOristockProductEntity.setProduceDate(produceDate);
            warehouseOristockProductEntity.setGuaranteePeriod(guaranteePeriod * TimeConstant.SECONDS_PER_DAY);
            addWarehouseOristockProductEntityList.add(warehouseOristockProductEntity);

            InstockProductEntity instockProductEntity = new InstockProductEntity();
            instockProductEntity.setProductNum(warehouseOristockProductEntity.getOristockNum());
            instockProductEntity.setCost(cost);
            instockProductEntity.setProductId(dataId);
            instockProductEntity.setWarehouseId(warehouseId);
            instockProductEntity.setBatch(batch);
            instockProductEntity.setProduceDate(produceDate);
            if (Objects.isNull(guaranteePeriod)) {
                instockProductEntity.setGuaranteePeriod(0L);
            } else {
                instockProductEntity.setGuaranteePeriod(guaranteePeriod * TimeConstant.SECONDS_PER_DAY);
            }
            instockProductEntity.setWarehouseName(warehouseName);
            instockProductEntity.setParentId(parentId);
            instockProductList.add(instockProductEntity);
        }
        Integer warehouseOristockId = 0;
        try {
            // 保存期初
            WarehouseOristockEntity entity = new WarehouseOristockEntity(null,corpid,oriStockSaveDTO.getAppId(),oriStockSaveDTO.getMenuId(),0L,oriStockSaveDTO.getSerialNo(), null, null, 0L, dataList, oriStockSaveDTO.getUserId(),  warehouseId);
            warehouseOristockId = warehouseOristockModel.insert(entity);
            for (WarehouseOristockProductEntity item: addWarehouseOristockProductEntityList) {
                item.setOristockId(warehouseOristockId);
            }
            if (!addWarehouseOristockProductEntityList.isEmpty()){
                warehouseOristockProductModel.insertBatch(addWarehouseOristockProductEntityList);
                // 序列号入库
                insertBatchSerial(addWarehouseOristockProductEntityList, warehouseOristockId, warehouseId, oriStockSaveDTO.getSerialNo(), corpid);
            }
            // 更新仓库期初状态
            warehouseJsonData.put(WarehouseEnum.ORI_STOCK.getAttr(),WarehouseOriStockEnum.NO_NEED.getCode());
            warehouseModel.update(warehouseEntityExt);
            // 更新分仓，批次库存
            instockProductService.addUpdateStock(instockProductList,corpid,true);
            SaasFormSaveDTO saasFormSaveDTO = new SaasFormSaveDTO();
            BeanUtil.copyProperties(oriStockSaveDTO, saasFormSaveDTO);
            saasFormSaveDTO.setBusinessType(XbbRefTypeEnum.ORI_STOCK.getCode());
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            paasFormDataEntity.setId(Long.valueOf(warehouseOristockId));
            paasFormDataEntity.setSerialNo(oriStockSaveDTO.getSerialNo());
            saasFormSaveDTO.setNewPaasFormDataEntity(paasFormDataEntity);
            saasFormSaveDTO.setNewData(dataList);
            for (int i = 0; i < productArr.size(); i++) {
                JSONObject jsonObject = productArr.getJSONObject(i);
                jsonObject.put(BusinessConstant.PRODUCT_SUB_ID, addWarehouseOristockProductEntityList.get(i).getId());
                jsonObject.put(ProductEnum.PARENT_ID.getSaasAttr(), addWarehouseOristockProductEntityList.get(i).getParentId());
            }
            //生成流水
            stockFlowBillService.caculateStockModification4Save(saasFormSaveDTO);
            batchFlowBillService.batchFlowModification4Save(saasFormSaveDTO);
        } catch (XbbException e) {
            proEsHelper.physicalDeleteAllInAdd(Long.valueOf(warehouseOristockId),corpid,XbbRefTypeEnum.ORI_STOCK.getCode(), SaasMarkEnum.SAAS.getCode());
            throw e;
        } catch (Exception e) {
            LOG.error("workOrderFormData 数据库保存表单数据出错", e);
            proEsHelper.physicalDeleteAllInAdd(Long.valueOf(warehouseOristockId),corpid,XbbRefTypeEnum.ORI_STOCK.getCode(), SaasMarkEnum.SAAS.getCode());
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        // 记录日志(有名称的格式为编号(名称)，无名称的格式为编号)
        String userId = oriStockSaveDTO.getUserId();
        String userName = oriStockSaveDTO.getLoginUserName();
        String memo;
        String warehouseStr = dataList.getString(OriStockEnum.WAREHOUSE.getAttr());
        if(!isImport){
            String oriStockNo = FastJsonHelper.getStringOrDefaultFromFormData(dataList, OriStockEnum.ORI_STOCK_NO.getAttr(), "");
            memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_ADD_WORK), userName, XbbRefTypeEnum.ORI_STOCK.getName(), oriStockNo);
            mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.ORI_STOCK, OperateTypeEnum.NEW,
                    warehouseStr, oriStockNo, memo, oriStockSaveDTO.getHttpHeader());
        }
        formDataAddVO.setMsg(I18nMessageUtil.getMessage(PaasConstant.FORM_ADD_RETURN_MSG));
        formDataAddVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
        return formDataAddVO;
    }

    private void insertBatchSerial(List<WarehouseOristockProductEntity> addWarehouseOristockProductEntityList, Integer warehouseOristockId, Long warehouseId, String serialNo, String corpid) throws XbbException {
        Map<String, Object> oriStockParam = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        oriStockParam.put(ParameterConstant.CORPID, corpid);
        oriStockParam.put("oriStockId", warehouseOristockId);
        oriStockParam.put(ParameterConstant.DEL, DelEnum.NORMAL.getDel());
        List<WarehouseOristockProductEntity> warehouseOristockProductEntitys = warehouseOristockProductModel.findEntitys(oriStockParam);
        List<ProductSerialFlowEntity> productSerialFlowEntityList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        List<ProductSerialBalanceEntity> productSerialBalanceList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (int i = 0; i < addWarehouseOristockProductEntityList.size(); i++) {
            WarehouseOristockProductEntity oristockProductEntity = addWarehouseOristockProductEntityList.get(i);
            JSONObject oristockProductData = oristockProductEntity.getData();
            JSONArray seqArray = oristockProductData.getJSONArray(ProductConstant.SEQ);
            if (Objects.isNull(seqArray) || seqArray.isEmpty()) {
                continue;
            }
            Long productId = oristockProductEntity.getProductId();
            Long parentId = oristockProductEntity.getParentId();
            WarehouseOristockProductEntity WarehouseOristockProductEntity = warehouseOristockProductEntitys.get(i);
            for (int j = 0; j < seqArray.size(); j++) {
                JSONObject seqData = seqArray.getJSONObject(j);
                String serial = seqData.getString(SerialEnum.SERIAL.getAttr());
                ProductSerialFlowEntity productSerialFlowEntity = new ProductSerialFlowEntity();
                productSerialFlowEntity.setCorpid(corpid);
                productSerialFlowEntity.setProductId(productId);
                productSerialFlowEntity.setParentId(parentId);
                productSerialFlowEntity.setSeq(serial);
                productSerialFlowEntity.setMemo(seqData.getString(SerialEnum.MEMO.getAttr()));
                productSerialFlowEntity.setStatus(0);
                productSerialFlowEntity.setDate(DateTimeUtil.getInt());
                productSerialFlowEntity.setBusinessType(XbbRefTypeEnum.ORI_STOCK.getCode());
                productSerialFlowEntity.setRefId(Long.valueOf(oristockProductEntity.getOristockId()));
                productSerialFlowEntity.setWarehouseId(warehouseId);
                productSerialFlowEntity.setSeqKey(productId + "_" + serial);
                productSerialFlowEntity.setDel(BasicConstant.ZERO);
                productSerialFlowEntity.setRefSheetNo(serialNo);
                productSerialFlowEntity.setRefProductId(WarehouseOristockProductEntity.getId());

                productSerialFlowEntityList.add(productSerialFlowEntity);
            }
        }
        if (CollectionUtils.isNotEmpty(productSerialFlowEntityList)) {
            for (ProductSerialFlowEntity entity : productSerialFlowEntityList) {
                ProductSerialBalanceEntity productSerialBalanceEntity = new ProductSerialBalanceEntity(entity);
                productSerialBalanceList.add(productSerialBalanceEntity);
            }
            productSerialBalanceModel.insertBatch(productSerialBalanceList);
            productSerialFlowModel.insertBatch(productSerialFlowEntityList);
        }
    }

    public void deleteByWarehouseId(String corpid, List<Long> dataIdIn) throws XbbException {
        List<Integer> oriIdList = warehouseOristockModel.deleteByWarehouseId(corpid,dataIdIn);
        if (oriIdList.isEmpty()) {
            return;
        }
        warehouseOristockProductModel.deleteByOriId(corpid,oriIdList);
    }

    @Override
    public void deleteBatch(WarehouseOriDeleteBatchDTO warehouseOriDeleteBatchDTO) throws XbbException {
        String corpid = warehouseOriDeleteBatchDTO.getCorpid();
        List<Long> warehouseIdList = warehouseOriDeleteBatchDTO.getDataIdList();
        //被锁的仓库id
        List<Long> lackIdList = new ArrayList<>();
        try {
            //流水启用校验
            String limit = paasRedisHelper.getValue(RedisPrefixConstant.PRODUCE_STOCK_FLOW, corpid);
            if (StringUtil.isNotEmpty(limit)) {
                throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212036);
            }
            //分仓关系
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("warehouseIdIn", warehouseIdList);
            List<WarehouseOristockEntity> warehouseOristockEntityList = warehouseOristockModel.findEntitys(param);
            if (warehouseOristockEntityList.isEmpty()) {
                return;
            }
            List<Long> oriStockIdList = new ArrayList<>();
            List<Integer> oriStockIdIntList = new ArrayList<>();
            Map<Long, String> instockIdAndno= new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            warehouseOristockEntityList.forEach(item -> {
                oriStockIdList.add(Long.valueOf(item.getId()));
                oriStockIdIntList.add(item.getId());
                instockIdAndno.put(Long.valueOf(item.getId()),item.getSerialNo());
            });
            //删除锁校验
            lackIdList = checkRedisKey(corpid, oriStockIdList);
            lackMsg(lackIdList, corpid);
            param.clear();
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("oriStockIdIn", oriStockIdList);
            List<WarehouseOristockProductEntity> warehouseOristockProductEntityList = warehouseOristockProductModel.findEntitys(param);
            Long warehouseId = warehouseIdList.get(0);

            List<String> warehouseKeyList = new ArrayList<>();
            List<Long> delOriStockProductIdList = new ArrayList<>();
            //mock成入库单，调用入库单删除方法来更新库存
            List<InstockProductEntity> mockInstockProductDelList = new ArrayList<>();
            List<StockFlowBillUpdateEntity> stockFlowBillUpdateList = new ArrayList<>();
            List<BatchFlowBillUpdateEntity> batchFlowBillUpdateEntityList = new ArrayList<>();
            for (WarehouseOristockProductEntity entity : warehouseOristockProductEntityList) {
                if (Objects.isNull(entity.getCost())) {
                    entity.setCost(0D);
                }
                InstockProductEntity instockProductEntity = new InstockProductEntity();
                instockProductEntity.setCorpid(entity.getCorpid());
                instockProductEntity.setIntoWarehouseId(Long.valueOf(entity.getOristockId()));
                instockProductEntity.setProductName(entity.getProductName());
                instockProductEntity.setProductNum(entity.getOristockNum());
                instockProductEntity.setCost(entity.getCost());
                instockProductEntity.setWarehouseId(warehouseId);
                instockProductEntity.setProductSpecification(entity.getSpec());
                instockProductEntity.setParentId(entity.getParentId());
                instockProductEntity.setProductId(entity.getProductId());
                instockProductEntity.setBatch(entity.getBatch());
                instockProductEntity.setGuaranteePeriod(entity.getGuaranteePeriod());
//                if (Objects.isNull(entity.getGuaranteePeriod())) {
//                    instockProductEntity.setGuaranteePeriod(0L);
//                } else {
//                    instockProductEntity.setGuaranteePeriod(entity.getGuaranteePeriod() * TimeConstant.SECONDS_PER_DAY);
//                }
                instockProductEntity.setProduceDate(entity.getProduceDate());
                instockProductEntity.setAddTime(entity.getAddTime());
                mockInstockProductDelList.add(instockProductEntity);

                stockFlowBillUpdateList.add(new StockFlowBillUpdateEntity(entity.getProductId() + "_" + warehouseId, Arith.sub(0D, entity.getOristockNum()), Arith.mul(Arith.sub(0D, entity.getOristockNum()), entity.getCost()), DateTimeUtil.getTodayInt(entity.getAddTime()), DateTimeUtil.getInt(), Long.valueOf(entity.getOristockId())));
                warehouseKeyList.add(entity.getProductId() + "_" + warehouseId);
//                warehouseKeyMap.put(entity.getProductId() + "_" + warehouseId, instockProductEntity);
                delOriStockProductIdList.add(entity.getId());
            }
            //序列号校验
            productSerialService.preCheckDelSerial(oriStockIdList, corpid, XbbRefTypeEnum.ORI_STOCK.getCode());
            //批次序列号校验
            Set<Long> disableBatchProducts = saasDeleteHelp.checkDocumentDelete(corpid, null, mockInstockProductDelList, instockIdAndno);

            Map<String,InstockProductEntity> warehouseKeyMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            Map<String,InstockProductEntity> batchKeyMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (InstockProductEntity entity : mockInstockProductDelList) {
                entity.setTransferNum(entity.getProductNum());
                if (disableBatchProducts.contains(entity.getParentId())) {
                    String key = entity.getProductId() + "_" + entity.getWarehouseId();
                    if (warehouseKeyMap.containsKey(key)) {
                        InstockProductEntity instockProductEntity = warehouseKeyMap.get(key);
                        instockProductEntity.setTransferNum(Arith.add(instockProductEntity.getTransferNum(),entity.getTransferNum()));
                        warehouseKeyMap.put(key,instockProductEntity);
                    } else {
                        warehouseKeyMap.put(key,entity);
                    }
                } else {
                    String key = formDataValidateProductHelp.getBatchKey(entity.getProductId(), entity.getWarehouseId(), entity.getBatch(), entity.getProduceDate(), entity.getGuaranteePeriod());
                    if (batchKeyMap.containsKey(key)) {
                        InstockProductEntity instockProductEntity = batchKeyMap.get(key);
                        instockProductEntity.setTransferNum(Arith.add(instockProductEntity.getTransferNum(),entity.getTransferNum()));
                        batchKeyMap.put(key,instockProductEntity);
                    } else {
                        batchKeyMap.put(key,entity);
                    }
                }
                if (StringUtil.isNotEmpty(entity.getBatch()) && !disableBatchProducts.contains(entity.getParentId())) {
                    BatchFlowBillUpdateEntity batchFlowBillUpdateEntity = new BatchFlowBillUpdateEntity(entity.getProductId() + "_" + entity.getWarehouseId() + "_" + entity.getBatch() + "_" + entity.getProduceDate() + "_" + entity.getGuaranteePeriod(), Arith.sub(0D, entity.getProductNum()),Arith.mul(Arith.sub(0D, entity.getProductNum()), entity.getCost()), entity.getAddTime(), DateTimeUtil.getInt(), entity.getIntoWarehouseId());
                    batchFlowBillUpdateEntityList.add(batchFlowBillUpdateEntity);
//                    batchInstockId.add(item.getIntoWarehouseId());
                }
            }
            //库存校验
            instockService.negativeStockCheck(corpid, warehouseKeyMap, batchKeyMap);

            param.clear();
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("warehouseKeyIn", warehouseKeyList);
            //未解绑的分仓
            List<ProductWarehouseEntity> productWarehouseEntityList = productWarehouseModel.findEntitysWithWarehouseChecked(param, 1);
            if (productWarehouseEntityList.size() < warehouseOristockProductEntityList.size()) {
                List<String> existWarehouseKeyList = productWarehouseEntityList.stream().map(ProductWarehouseEntity::getWarehouseKey).collect(Collectors.toList());
                warehouseKeyList.removeAll(existWarehouseKeyList);
                for (String warehouseKey : warehouseKeyList) {
                    InstockProductEntity instockProductEntity = warehouseKeyMap.get(warehouseKey);
                    WarehouseEntityExt warehouseEntityExt = warehouseModel.getByKey(warehouseId, corpid);
                    throw new XbbException(ProductErrorCodeEnum.API_ERROR_205093, String.format(ProductErrorCodeEnum.API_ERROR_205093.getMsg(), instockProductEntity.getProductName(), warehouseEntityExt.getData().getString(WarehouseEnum.WAREHOUSE_NAME.getAttr())));
                }

            }

            List<Long> productWarehouseIdList = productWarehouseEntityList.stream().map(ProductWarehouseEntity::getId).collect(Collectors.toList());
            WarehouseOristockEntity warehouseOristockEntity = warehouseOristockEntityList.get(0);
            //删除期初，单据日期校验
            //结账中校验
            String redisHelperValue = paasRedisHelper.getValue(RedisPrefixConstant.SETTLE_ACCOUNTS, corpid);
            if (StringUtil.isNotEmpty(redisHelperValue)) {
                if (warehouseOristockEntity.getAddTime() <= DateTimeUtil.getTodayEndInt(Long.valueOf(redisHelperValue))){
                    throw new XbbException(SettleAccountErrorCodeEnum.API_ERROR_254007);
                }
            }
            SettleAccountsEntity accountsEntity = settleAccountsModel.getLastSettleAccounts(corpid);
            //校验日期是否受结账限制
            if (Objects.nonNull(accountsEntity) && Objects.nonNull(accountsEntity.getCheckOutTime())) {
                if (warehouseOristockEntity.getAddTime() <= DateTimeUtil.getTodayEndInt(accountsEntity.getCheckOutTime())) {
                    throw new XbbException(OutstockErrorCodeEnum.API_ERROR_212032);
                }
            }
            warehouseOristockModel.deleteByWarehouseId(corpid, Collections.singletonList(warehouseId));
            productSerialService.deleteSerial(corpid, oriStockIdList, XbbRefTypeEnum.ORI_STOCK.getCode());
            warehouseOristockProductModel.deleteByOriId(corpid, oriStockIdIntList);
            Map<Long, ProductStockUpdateEntity> productAddMap = instockProductService.delUpdateStock(mockInstockProductDelList, corpid, true,disableBatchProducts);
            productService.updateProductStock(productAddMap, corpid);
            //流水删除
            stockFlowBillService.caculateStockModification4Delete(oriStockIdList, stockFlowBillUpdateList, XbbRefTypeEnum.ORI_STOCK.getCode(), corpid);
            batchFlowBillService.batchFlowModification4Delete(oriStockIdList, batchFlowBillUpdateEntityList, XbbRefTypeEnum.ORI_STOCK.getCode(), corpid);
            //分仓期初库存字段置为0
//        productWarehouseModel.reSetOriNum(productWarehouseIdList,corpid);
            //仓库期初标识更新
            param.clear();
            param.put(StringConstant.CORPID, corpid);
            param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
            param.put("warehouseId", warehouseId);
            Integer count = instockProductModel.getEntitysCount(param);
            if (count == 0) {
                count = outstockProductModel.getEntitysCount(param);
            }
            List<UpdateDataEntity> updateList = new ArrayList<>();
            JSONObject data = new JSONObject();
            //有出入库，无需录入；没有，未完成
            data.put(WarehouseEnum.ORI_STOCK.getAttr(), count > 0 ? WarehouseOriStockEnum.NO_NEED.getCode() : WarehouseOriStockEnum.NOT_DONE.getCode());
            updateList.add(ExplainUtil.getUpdateData(warehouseId, data, corpid));
            warehouseModel.updateBatch(updateList, corpid);



            List<String> inProductStrList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (WarehouseOristockProductEntity entity : warehouseOristockProductEntityList) {
                Double productNum = entity.getOristockNum() == null ? 0D : entity.getOristockNum();
                Double cost = entity.getCost() == null ? 0D : entity.getCost();
                // 拼接产品信息
                String productName = entity.getProductName() == null ? "--" : entity.getProductName();
                String productNo = entity.getProductNo() == null ? "--" : entity.getProductNo();
                String productSpecification = Objects.equals(entity.getSpec(), "") ? "--" : entity.getSpec();
//                productSpecification = productSpecification.replaceAll("[`~!@#$%^&*\",.，。【】“”'‘’()+=|{}'.;'\\[\\]<>/?~@#￥%……&*]|\\s*|\t|\r|\n", "");
                if (productSpecification.contains(":")) {
                    productSpecification = productSpecification.replace(":", "/");
                }
                String batch = Objects.equals(entity.getBatch(), "") ? "--" : entity.getBatch();
                StringBuilder sb = new StringBuilder();
                sb.append("产品名称：").append(productName).append("，").append("产品编号：").append(productNo).append("，")
                        .append("规格：").append(productSpecification).append("，")
                        .append("期初数量：").append(productNum).append("，").append("成本：").append(cost).append("，")
                        .append("批次号：").append(batch).append("；<br/>");
                inProductStrList.add(sb.toString());
            }
            List<String> list = new ArrayList<>();
            String outstockProductStr = StringUtils.join(inProductStrList, "，");
            StringBuilder sb = new StringBuilder();
            sb.append(warehouseOristockEntity.getSerialNo()).append("<br/>").append("（").append(outstockProductStr).append("）");
            list.add(sb.toString());
            String nameStr = StringUtils.join(list, "，<br/>");

            Long instockLogId = Long.valueOf(warehouseOristockEntity.getId());
            String serialNo = warehouseOristockEntity.getSerialNo();
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), warehouseOriDeleteBatchDTO.getLoginUserName(), XbbRefTypeEnum.ORI_STOCK.getName(), serialNo);
            List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            InfoArrPojo infoArrPojo = new InfoArrPojo();
            infoArrPojo.setTitle(OriStockEnum.PRODUCT_DETAIL.getAttrName());
            infoArrPojo.setContent(nameStr);
            infoArrPojoList.add(infoArrPojo);
            mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, warehouseOriDeleteBatchDTO.getUserId(), warehouseOriDeleteBatchDTO.getLoginUserName(), OperateModuleTypeEnum.ORI_STOCK, OperateTypeEnum.DELETE,
                    instockLogId.toString(), serialNo, memo, warehouseOriDeleteBatchDTO.getHttpHeader());
        }catch (XbbException e) {
            removeDelLack(lackIdList,corpid);
            throw e;
        } catch (Exception e) {
            removeDelLack(lackIdList,corpid);
            LOG.error("instockServiceImpl.deleteBatch 批量删除出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
    }

    private void removeDelLack(List<Long> dataIdList, String corpid) {
        for (Long dataId : dataIdList) {
            String key = corpid + "_" + dataId;
            paasRedisHelper.removeValue(RedisPrefixConstant.ORI_STOCK_DEL,key);
        }
    }

    /**
     * 并发锁抛错
     * @param lackIdList
     * @param corpid
     * @throws XbbException
     */
    private void lackMsg(List<Long> lackIdList, String corpid) throws XbbException {
        if (!lackIdList.isEmpty()){
            Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            map.put(StringConstant.CORPID,corpid);
            map.put("idIn",lackIdList);
            map.put("columns","serial_no");
            List<WarehouseEntityExt> warehouseEntityExtList = warehouseModel.findEntitys(map);
            StringBuilder stringBuilder = new StringBuilder();
            warehouseEntityExtList.forEach(item -> stringBuilder.append(item.getSerialNo()).append(","));
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100404, ErrorMessageConstant.DATA_DEL_LACK_ERROR_MSG,stringBuilder.toString());
        }
    }

    /**
     * 校验并发
     * @param corpid
     * @param dataIdList
     * @return
     */
    private List<Long> checkRedisKey(String corpid, List<Long> dataIdList) {
        Iterator<Long> iterator = dataIdList.iterator();
        List<Long> lackIdList = new ArrayList<>();
        while (iterator.hasNext()){
            Long dataId = iterator.next();
            String key = corpid + "_" + dataId;
            Long value = paasRedisHelper.getIncrNum(RedisPrefixConstant.ORI_STOCK_DEL,key, TimeConstant.SECONDS_PER_MINUTE,1,1);
            if (value > 1L){
                lackIdList.add(dataId);
                iterator.remove();
            }
        }
        return lackIdList;
    }

    @Override
    public void reSetWarehouseOriStock(String corpid, Set<Long> warehouseIdList) throws XbbException {
//        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//        map.put(StringConstant.CORPID,corpid);
//        map.put(StringConstant.DEL,DelEnum.NORMAL.getDel());
//        map.put("warehouseIdIn",warehouseIdList);
//        map.put(StringConstant.COLUMNS,"DISTINCT warehouse_id");
        if (warehouseIdList.isEmpty()) {
            return;
        }
        Set<Long> dbWarehouseIdList = instockProductModel.getWarehouseIdUnion(warehouseIdList, corpid);
        warehouseIdList.removeAll(dbWarehouseIdList);
        if (!warehouseIdList.isEmpty()) {
            dbWarehouseIdList = outstockProductModel.getWarehouseIdUnion(warehouseIdList, corpid);
            warehouseIdList.removeAll(dbWarehouseIdList);
            if (!warehouseIdList.isEmpty()) {
                dbWarehouseIdList = warehouseOristockModel.getWarehouseIdUnion(warehouseIdList, corpid);
                warehouseIdList.removeAll(dbWarehouseIdList);

            }
            List<UpdateDataEntity> updateList = new ArrayList<>();
            for (Long warehouseId : warehouseIdList) {
                JSONObject data = new JSONObject();
                data.put(WarehouseEnum.ORI_STOCK.getAttr(),WarehouseOriStockEnum.NOT_DONE.getCode());
                updateList.add(ExplainUtil.getUpdateData(warehouseId,data,corpid));
            }
            if (!updateList.isEmpty()) {
                warehouseModel.updateBatch(updateList,corpid);
            }
        }
    }
}
